package cn.bugstack.mybatis.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

/**
 * Resources类提供了多种静态方法，用于操作和获取资源文件，
 * 包括将资源文件作为Reader读取、作为InputStream获取、以及加载类等。
 */
public class Resources {

    /**
     * 将指定资源文件作为Reader返回。
     *
     * @param resource 资源文件的路径
     * @return Reader对象，用于读取资源文件内容
     * @throws IOException 如果无法找到或读取资源文件
     */
    public static Reader getResourceAsReader(String resource) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(getResourceAsStream(resource));
        return inputStreamReader;
    }

    /**
     * 获取指定资源文件的InputStream。
     *
     * @param resource 资源文件的路径
     * @return 资源文件的InputStream
     * @throws IOException 如果无法找到资源文件
     */
    public static InputStream getResourceAsStream(String resource) throws IOException {
        ClassLoader[] classLoaders = getClassLoader(); // 获取可能的类加载器数组
        for (ClassLoader classLoader : classLoaders) {
            InputStream resourceAsStream = classLoader.getResourceAsStream(resource);
            if (resourceAsStream != null) {
                return resourceAsStream; // 如果找到资源，则返回其InputStream
            }
        }
        throw new IOException("Could not find resource " + resource); // 如果所有类加载器都无法找到资源，抛出异常
    }

    /**
     * 获取可能用到的类加载器数组。
     *
     * @return 类加载器数组，包括系统类加载器和当前线程的上下文类加载器
     */
    public static ClassLoader[] getClassLoader() {
        return new ClassLoader[]{
                ClassLoader.getSystemClassLoader(),
                Thread.currentThread().getContextClassLoader()
        };
    }

    /**
     * 根据类名加载类。
     *
     * @param classname 待加载的类名
     * @return 加载的类的Class对象
     */
    public static Class<?> classForName(String classname) {
        Class<?> aClass = null;
        try {
            aClass = Class.forName(classname); // 尝试加载类
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(classname + " class not find",e); // 如果类未找到，抛出运行时异常
        }
        return aClass;
    }

}

